﻿using System;

namespace EventDemo2
{
    /// <summary>
    /// 热水器类
    /// </summary>
    public class Heater
    {
        private int temperature;                        //水温
        public string type = "RealFire 001";            //型号
        public string area = "China";                   //产地
        public delegate void BoiledEventHandler(object sender, BoiledEventArgs e);    //声明委托
        public event BoiledEventHandler Boiled;             //声明事件

        /// <summary>
        /// 定义BoiledEventArgs类，传递给Observer所感兴趣的信息
        /// </summary>
        public class BoiledEventArgs : EventArgs
        {
            public readonly int temperature;
            public BoiledEventArgs(int temperature)
            {
                this.temperature = temperature;
            }
        }

        /// <summary>
        /// 可以供继承Heater的类重写，以便继承类拒绝其他对象对它的监视
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnBoiled(BoiledEventArgs e)
        {
            if (Boiled != null)         //如果有对象注册
            {
                Boiled(this, e);        //调用所有注册对象的方法
            }
        }

        /// <summary>
        /// 烧水
        /// </summary>
        public void BoilWater()
        {
            for (int i = 0; i <= 100; i++)
            {
                temperature = i;

                if (temperature > 95)
                {
                    BoiledEventArgs e = new BoiledEventArgs(temperature);   //建立BoiledEventArgs对象
                    OnBoiled(e);                                            //调用OnBoiled方法
                }
            }
        }
    }

    /// <summary>
    /// 警报器
    /// </summary>
    public class Alarm
    {
        /// <summary>
        /// 发出语音警报
        /// </summary>
        /// <param name="param"></param>
        public void MakeAlert(object sender, Heater.BoiledEventArgs e)
        {
            Heater heater = (Heater)sender;
            Console.WriteLine("Alarm：产地-{0}，类型-{1}", heater.area, heater.type);
            Console.WriteLine("Alarm：滴滴滴，水已经{0}度了", e.temperature);
            Console.WriteLine();
        }
    }

    /// <summary>
    /// 显示器
    /// </summary>
    public class Display
    {
        /// <summary>
        /// 显示水温
        /// </summary>
        /// <param name="param"></param>
        public static void ShowMsg(object sender, Heater.BoiledEventArgs e)
        {
            Heater heater = (Heater)sender;
            Console.WriteLine("Display：产地-{0}，类型-{1}", heater.area, heater.type);
            Console.WriteLine("Display：水快开了，当前温度：{0}度", e.temperature);
            Console.WriteLine();
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Heater heater = new Heater();
            Alarm alarm = new Alarm();

            heater.Boiled += alarm.MakeAlert;            //注册方法
            heater.Boiled += (new Alarm()).MakeAlert;    //为匿名对象注册方法
            heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert);    //也可以这样注册
            heater.Boiled += Display.ShowMsg;            //注册静态方法

            heater.BoilWater();                             //烧水，会自动调用注册过对象的方法
        }
    }
}
